home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / NewControl-p / Original / CONTROL.TEXT next >
Encoding:
Text File  |  1994-12-04  |  18.1 KB  |  564 lines  |  [TEXT/EDIT]

  1. {$X-}   {Turn off stack expansion. This is a Lisa concept, not needed on Mac}
  2. {$U-}   {Turn off the Lisa Libraries. This is required by the WorkShop}
  3. {$R-}   {Turn off range checking}
  4.  
  5. PROGRAM ScrollControls;
  6.  
  7. {Jeffery J. Bradford    Macintosh Technical Support  April 1985 }
  8.  
  9. {This example will help you become familiar with how scroll bars work}
  10. {and allow you manipulate the contents of a window. This particular  }
  11. {example remembers where the drawing origin should be and sets the   }
  12. {origin to that spot before drawing every time. This involves some   }
  13. {book keeping, but we've made it pretty simple and minimized globals.}
  14.  
  15.  
  16. USES
  17.     {$U Obj/Memtypes  } MemTypes,
  18.     {$U Obj/QuickDraw } QuickDraw,
  19.     {$U Obj/OSIntf    } OSIntf,
  20.     {$U Obj/ToolIntf  } ToolIntf,
  21.     {$U Obj/PackIntf  } PackIntf;
  22.  
  23. CONST
  24. {menu stuff}
  25.     AppleMenu = 256;
  26.     FileMenu  = 257;
  27.     EditMenu  = 258;
  28.  
  29. {window IDs}
  30.     WindResID = 256;
  31.  
  32. {scroll bar res IDs}
  33.     VScrollBar = 256;      {res ID for bottom/horz scroll bar}
  34.     HScrollBar = 257;      {res ID for side/vert scroll bar}
  35.  
  36. {control stuff}
  37.     didntFindaControl= 0;     {used in IF statements for clarity}
  38.     didntMove        = 0;     {used in IF statements for clarity}
  39.     VSBarWidth       = 15;    {width of vertical scroll bar}
  40.     HSBarHeight      = 15;    {width of horz. scroll bar}
  41.     Line_Inc         = 5;     {amount of scrolling per button press}
  42.     Page_Inc         = 100;   {amount of scrolling per page press}
  43.     HorzScrollBar    = 1;     {used to distinguish between vert & horz scroll bar}
  44.     VertScrollBar    = 0;     {used to distinguish between vert & horz scroll bar}
  45.  
  46.  
  47.  
  48. TYPE
  49. {this is useful stuff you might need sometime}
  50.  
  51.     WordStuff = Packed Record
  52.        Case Integer of
  53.          0: (Word: Integer);
  54.          1: (SByte1,SByte0: SignedByte);
  55.          2: (b15,b14,b13,b12,b11,b10,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0: Boolean)
  56.        End;
  57.  
  58.     CharStuff = Packed Record
  59.          chr3,chr2,chr1,chr0: char;
  60.        End;
  61.  
  62.     LMwordPtr = ^Integer;          {pointer to low memory address}
  63.     LMLongPtr = ^LongInt;          {pointer to low memory address - long}
  64.  
  65.  
  66.  
  67. VAR
  68. {global program stuff}
  69.     Finished:      Boolean;    {used to terminate the program}
  70.     ClockCursor:   CursHandle; {handle to the waiting watch cursor}
  71.  
  72. {Screen stuff}
  73.     DragArea:   Rect;          {holds the area where window can be dragged in}
  74.     GrowArea:   Rect;          {holds the area to which a window's size can change}
  75.     Screen:     Rect;          {holds the screen dimensions}
  76.  
  77. {Window stuff}
  78.     OneWindow:  WindowPtr;     {pointer to the first window}
  79.     UsableArea: Rect;          {uasable area of the windows content region}
  80.  
  81. {-----------------------------------------------------------------------------
  82.                      end of global variable definition
  83. -----------------------------------------------------------------------------}
  84.  
  85. PROCEDURE DrawBullseye;
  86.   {this will draw a bullseye that is 700 by 700 pixels }
  87.   Var TempRect:Rect;
  88.       i,a,b,x:integer;
  89.   Begin
  90.      MoveTo(0,0);    LineTo(700,700);
  91.      MoveTo(0,350);  LineTo(700,350);
  92.      MoveTo(0,700);  LineTo(700,0);
  93.      MoveTo(350,0);  LineTo(350,700);
  94.  
  95.     a := 0;
  96.     b := 700;
  97.     For i := 0 to 11 do
  98.     begin
  99.       x := 56 - i*5;
  100.       a := a + x;
  101.       b := b - x;
  102.       SetRect(TempRect,a,a,b,b);
  103.       FrameRect(TempRect);
  104.     end;
  105.  
  106.     FillRect(TempRect,black);
  107. End;
  108.  
  109. {-----------------------------------------------------------------------------}
  110.  
  111. PROCEDURE DrawDisplay;
  112. Var TempRect:  Rect;  {used for offseting the Usable display area}
  113.     CurOrigin: Point; {holds the current origin}
  114.  
  115. Begin
  116. {in order to confine the drawing to the usable content area of the window}
  117. {we will set a clipRect of that area}
  118.  
  119.   TempRect := UsableArea;
  120.   CurOrigin := Point(GetWRefCon(OneWindow));     {get the current origin}
  121.  
  122. {set up to draw properly, and change the clip}
  123.   SetOrigin(CurOrigin.h, CurOrigin.v);           {account for scrolling}
  124.   OffsetRect(TempRect,CurOrigin.h, CurOrigin.v); {account for scrolling}
  125.   ClipRect(TempRect);
  126.  
  127.   DrawBullseye;
  128.  
  129.   SetOrigin(0,0);                   {reset it back to normal}
  130.   ClipRect(OneWindow^.portRect);   {reset it to the original window}
  131. End;
  132.  
  133. {-----------------------------------------------------------------------------}
  134.  
  135. PROCEDURE ScrolltheScreen(cntlHdl:ControlHandle);
  136. Var
  137.    Origin:     Point;     {holds the coordinates of the new & old origin}
  138. {  OldOrigin:  Point;      holds the coordinates of the old/last origin}
  139. {  NewOrigin:  Point;      holds the coordinates of the new origin}
  140.   delta_H:    Integer;
  141.   delta_V:    Integer;
  142.   UpDateRgn:  RgnHandle;  {holds the region to be scrolled}
  143.  
  144. Begin
  145.  
  146. (*  Code below is for clarity
  147. {get the current (or old) origin}
  148.   OldOrigin := Point(GetWRefCon(OneWindow));
  149.  
  150. {get the NEW origin, we can only scroll in one direction at a time so}
  151.   If GetCRefCon(CntlHdl) = VertScrollBar
  152.   Then begin
  153.          NewOrigin.v := GetCtlValue(CntlHdl);     {get the new V-value}
  154.          NewOrigin.h := OldOrigin.h;              {use the old H-value}
  155.        end
  156.   Else begin
  157.          NewOrigin.h := GetCtlValue(CntlHdl);     {get the new H-value}
  158.          NewOrigin.v := OldOrigin.v;              {use the old V-value}
  159.        end;
  160.  
  161. {now find the difference between the old and new origins}
  162.   delta_H := OldOrigin.h - NewOrigin.h;     {get the horizontal change}
  163.   delta_V := OldOrigin.v - NewOrigin.v;     {get the vertical change}
  164. *)
  165.  
  166.   Origin := Point(GetWRefCon(OneWindow));
  167.   If GetCRefCon(CntlHdl) = VertScrollBar
  168.   Then begin
  169.          delta_H := 0;                                {didn't change}
  170.          delta_V := Origin.v - GetCtlValue(CntlHdl);  {get the diff}
  171.          Origin.v:= GetCtlValue(CntlHdl);             {set to new position}
  172.        end
  173.   Else begin
  174.          delta_V := 0;                                {didn't change}
  175.          delta_H := Origin.h - GetCtlValue(CntlHdl);  {get the diff}
  176.          Origin.h:= GetCtlValue(CntlHdl);             {set to new position}
  177.        end;
  178.  
  179.  
  180. {get a region for use in updating/scrolling the screen}
  181.   UpdateRgn := NewRgn;
  182.   ScrollRect(UsableArea, delta_H, delta_V, updateRgn);
  183.  
  184.   SetOrigin(Origin.h, Origin.v);  {set to the new origin}
  185.  
  186. {move the update Rgn to new location}
  187.   OffsetRect(updateRgn^^.rgnBBox, Origin.h, Origin.v);
  188.  
  189. {clip to it}
  190.   ClipRect(updateRgn^^.rgnBBox);
  191.  
  192.   DrawBullseye;         {do the drawing}
  193.  
  194. {reset everything back to normal & save the new origin}
  195.   SetOrigin(0,0);
  196.   ClipRect(OneWindow^.portRect);
  197.   SetWRefCon(OneWindow, LongInt(Origin));
  198.  
  199.   DisposeRgn(updateRgn);
  200. End;
  201.  
  202. {-----------------------------------------------------------------------------}
  203.  
  204. PROCEDURE LineScroll(SBar:ControlHandle; ControlLoc:integer);
  205. {get the buttons current value, set the increment and reset it with new value}
  206.  
  207. Begin
  208.   If ControlLoc = inUpButton
  209.   then SetCtlValue(SBar, GetCtlValue(SBar) - Line_inc)
  210.   else SetCtlValue(SBar, GetCtlValue(SBar) + Line_inc);
  211.  
  212.   ScrolltheScreen(SBar);
  213. End;
  214.  
  215. {-----------------------------------------------------------------------------}
  216.  
  217. PROCEDURE HandleControl_at(atMouseLoc:point; inThisWindow:WindowPtr);
  218. Var
  219.   CntlHdl:     ControlHandle;  {handle of a control part selected}
  220.   ControlLoc:  Integer;        {position ID of the control part selected}
  221.   dummy:       Integer;        {used to hold integer returned from TrackControl}
  222.  
  223. Begin
  224.   ControlLoc := FindControl(atMouseLoc, inThisWindow, CntlHdl);
  225.  
  226.   If ControlLoc <> didntFindaControl then
  227.     Case ControlLoc of
  228.  
  229.       inUpButton:   dummy:= TrackControl(CntlHdl,atMouseLoc,@LineScroll);
  230.  
  231.       inDownButton: dummy:= TrackControl(CntlHdl,atMouseLoc,@LineScroll);
  232.  
  233.       inPageUp:    begin
  234.                      SetCtlValue(CntlHdl, GetCtlValue(CntlHdl) - Page_inc);
  235.                      ScrolltheScreen(CntlHdl);
  236.                    end;
  237.  
  238.       inPageDown:  begin
  239.                      SetCtlValue(CntlHdl, GetCtlValue(CntlHdl) + Page_inc);
  240.                      ScrolltheScreen(CntlHdl);
  241.                    end;
  242.  
  243.       inThumb:     If TrackControl(CntlHdl,atMouseLoc,Nil) <> didntMove
  244.                       then ScrolltheScreen(CntlHdl);
  245.  
  246.     End;{case of control location}
  247. End;{of Handle Window Controls}
  248.  
  249. {-----------------------------------------------------------------------------}
  250.  
  251. PROCEDURE ProcessMenu_in(CodeWord:longint);
  252. Var
  253.   Menu_No:    integer;        {menu number that was selected}
  254.   Item_No:    integer;        {item in menu that was selected}
  255.   NameHolder: Str255;         {name holder for desk accessory or font}
  256.   DNA:        integer;        {OpenDA will never return 0, so don't care}
  257.  
  258. Begin
  259.   If CodeWord <> 0 then {go ahead and process the command}
  260.   begin
  261.     Menu_No := HiWord(CodeWord);   {get the Hi word of...}
  262.     Item_no := LoWord(CodeWord);   {get the Lo word of...}
  263.  
  264.     Case Menu_No of
  265.  
  266.      AppleMenu: Begin
  267.                   GetItem(GetMHandle(AppleMenu), Item_No, NameHolder);
  268.                   DNA := OpenDeskAcc(NameHolder);
  269.                 End;
  270.  
  271.       FileMenu: Begin
  272.                   Case Item_No of
  273.                     1: Finished := True;          {quit}
  274.                   End;
  275.                 End;
  276.  
  277.       EditMenu: Begin
  278.                   If Not SystemEdit(Item_no - 1) {if not for a desk accessory}
  279.                   then
  280.                     Case Item_No of
  281.                       1: begin end;               {undo}
  282.                     { 2:                           line divider}
  283.                       3: begin end;               {cut}
  284.                       4: begin end;               {copy}
  285.                       5: begin end;               {paste}
  286.                       6: begin end;               {clear}
  287.                     End;
  288.                 End;
  289.  
  290.     End;{case of Menu_No}
  291.  
  292.     HiliteMenu(0);               {unhilite after processing menu}
  293.   end; {the If codeword <> 0}
  294. End; {of ProcessMenu_in procedure}
  295.  
  296.  
  297. {-------------------------------------------------------------------}
  298. {----- These are procedures called from the main event loop  -------}
  299.  
  300. PROCEDURE DealwthMouseDowns(Event:EventRecord);
  301. Var WindowPointedTo: WindowPtr;
  302.     MouseLoc:Point;
  303.     WindoLoc:integer;
  304. Begin
  305.   MouseLoc := Event.Where;
  306.   WindoLoc := FindWindow(MouseLoc, WindowPointedTo);
  307.   Case WindoLoc of
  308.  
  309.      inMenuBar: ProcessMenu_in(MenuSelect(MouseLoc));
  310.  
  311.      inSysWindow: SystemClick(Event,WindowPointedTo);
  312.  
  313.      inContent: If WindowPointedTo <> FrontWindow
  314.                 then SelectWindow(WindowPointedTo)
  315.                 else begin
  316.                        GlobaltoLocal(MouseLoc);
  317.                        If Not PtinRect(MouseLoc,UsableArea)
  318.                        then HandleControl_at(MouseLoc, WindowPointedTo)
  319.                        else InvalRect(UsableArea);  {just for effect}
  320.                      end;
  321.  
  322.      inGrow:    If WindowPointedTo <> FrontWindow
  323.                 then SelectWindow(WindowPointedTo)
  324.                 else begin {ReSizeWindow(WindowPointedTo,MouseLoc);} end;
  325.  
  326.      inDrag   :DragWindow(WindowPointedTo,MouseLoc,DragArea);
  327.  
  328.      inGoAway :If TrackGoAway(WindowPointedTo,MouseLoc)
  329.                then DisposeWindow(WindowPointedTo); {since W mgr allocated space}
  330.  
  331.   End{ of case};
  332. End;
  333.  
  334. {-----------------------------------------------------------------------------}
  335.  
  336. PROCEDURE DealwthKeyDowns(Event:EventRecord);
  337. Var CharCode:char;
  338. Begin
  339.    CharCode:= CharStuff(Event.message).Chr0; {get low byte w/no processing}
  340.  
  341.   If BitAnd(Event.modifier,CmdKey) = CmdKey
  342.    then
  343.      begin  {key board command - probably a menu command}
  344.        ProcessMenu_in(MenuKey(CharCode));
  345.      end
  346.    else
  347.      begin
  348.        {regular keyboard entry}
  349.      end;
  350. End;
  351.  
  352. {-----------------------------------------------------------------------------}
  353.  
  354. PROCEDURE DealwthActivates(Event: EventRecord);
  355. Var TargetWindow:WindowPtr;
  356.     TargetPeek:  WindowPeek;
  357.     CntrlHdl:     ControlHandle;
  358. Begin
  359.    TargetWindow := WindowPtr(Event.message);
  360.    TargetPeek   := WindowPeek(TargetWindow);
  361.    DrawGrowIcon(TargetWindow);
  362.  
  363.    If Odd(Event.modifiers)
  364.  
  365.    then {the window is becoming active}
  366.      begin
  367. {1}    SetPort(TargetWindow);
  368.  
  369. {2}    {activate the window controls}
  370.        CntrlHdl := ControlHandle(TargetPeek^.ControlList);  {get the first one}
  371.        Repeat
  372.          If CntrlHdl <> Nil then   {in case we get a nil on the first one}
  373.          begin
  374.            ShowControl(CntrlHdl);
  375.            CntrlHdl := CntrlHdl^^.nextControl;
  376.          end;
  377.        Until CntrlHdl = NIL;
  378.  
  379. {3}   {activate selections, etc.}
  380.      end
  381.  
  382.  
  383.    else {the window is being DEactivatived}
  384.      begin
  385. {1}   {DEactivate the window controls}
  386.        CntrlHdl := ControlHandle(TargetPeek^.ControlList);  {get the first one}
  387.        Repeat
  388.          If CntrlHdl <> Nil then   {in case we get a nil on the first one}
  389.          begin
  390.            HideControl(CntrlHdl);
  391.            CntrlHdl := CntrlHdl^^.nextControl;
  392.          end;
  393.        Until CntrlHdl = NIL;
  394.  
  395. {2}    {deactivate selections, etc}
  396.      end;
  397. End;
  398.  
  399. {-----------------------------------------------------------------------------}
  400.  
  401. PROCEDURE DealwthUpdates(Event:EventRecord);
  402. Var UpDateWindow,
  403.           TempPort: WindowPtr;
  404. Begin
  405.    UpDateWindow := WindowPtr(Event.message);
  406.    GetPort(TempPort);                {Save the current port}
  407.  
  408.    SetPort    (UpDateWindow);      {set the port to one in Evt.msg}
  409.    BeginUpDate(UpDateWindow);
  410.      EraseRect(UsableArea);
  411.      DrawDisplay;
  412.      DrawControls(UpDateWindow);
  413.      DrawGrowIcon(UpDateWindow);
  414.    EndUpDate  (UpDateWindow);
  415.  
  416.    SetPort    (TempPort);             {restore to the previous port}
  417. End;
  418.  
  419. {-----------------------------------------------------------------------------}
  420.  
  421. PROCEDURE MainEventLoop;
  422. Var Event:EventRecord;
  423.     ProcessIt: Boolean;
  424. Begin
  425.   Repeat
  426.     SystemTask;             {so you can support Desk Accessories}
  427.  
  428.     ProcessIt := GetNextEvent(EveryEvent,Event);
  429.     If ProcessIt{is true} then {we'll ProcessIt}
  430.           Case Event.what of
  431.  
  432.             mouseDown  : DealwthMouseDowns(Event);
  433.             KeyDown    : DealwthKeyDowns  (Event);
  434.             ActivateEvt: DealwthActivates (Event);
  435.             UpDateEvt  : DealwthUpdates   (Event);
  436.  
  437.           End;{of Case}
  438.   Until Finished; {terminate the program}
  439. End;
  440.  
  441. {-----------------------------------------------------------------------------}
  442.  
  443. PROCEDURE InitThings;
  444. Begin
  445.   InitGraf(@thePort);          {create a grafport for the screen}
  446.  
  447.   MoreMasters;                 {extra pointer blocks at the bottom of the heap}
  448.   MoreMasters;                 {this is 5 X 64 master pointers}
  449.   MoreMasters;
  450.   MoreMasters;
  451.   MoreMasters;
  452.  
  453. {get the cursors we use and lock them down - no clutter}
  454.   ClockCursor := GetCursor(watchCursor);
  455.   HLock(Handle(ClockCursor));
  456.  
  457. {show the watch while we wait for inits & setups to finish}
  458.   SetCursor(ClockCursor^^);
  459.  
  460. {init everything in case the app is the Startup App}
  461.   InitFonts;                     {startup the fonts manager}
  462.   InitWindows;                   {startup the window manager}
  463.   InitMenus;                     {startup the menu manager}
  464.   TEInit;                        {startup the text edit manager}
  465.   InitDialogs(Nil);              {startup the dialog manager}
  466.  
  467.   Finished := False;             {set program terminator to false}
  468.   FlushEvents(everyEvent,0);     {clear events from previous program}
  469. End;
  470.  
  471. {-----------------------------------------------------------------------------}
  472.  
  473. PROCEDURE SetupLimits;
  474. Begin
  475.   Screen := ScreenBits.Bounds;   {set the size of the screen}
  476.   SetRect(DragArea,Screen.left+4,Screen.top+24,Screen.right-4,Screen.bottom-4);
  477.   SetRect(GrowArea,Screen.left,Screen.top+24,Screen.right,Screen.bottom);
  478. End;
  479.  
  480. {-----------------------------------------------------------------------------}
  481.  
  482. PROCEDURE SetupMenus;
  483. Var
  484.   MenuTopic: MenuHandle;
  485. Begin
  486.   MenuTopic := GetMenu(AppleMenu);  {get the apple desk accessories menu}
  487.   AddResMenu(MenuTopic,'DRVR');     {adds all names into item list}
  488.   InsertMenu(MenuTopic,0);          {put in list held by menu manager}
  489.  
  490.   MenuTopic := GetMenu(FileMenu);   {always need this for Quiting}
  491.   InsertMenu(MenuTopic,0);
  492.  
  493.   MenuTopic := GetMenu(EditMenu);   {always need for editing Desk Accessories}
  494.   InsertMenu(MenuTopic,0);
  495.  
  496.   DrawMenuBar;           {all done so show the menu bar}
  497. End;
  498.  
  499. {-----------------------------------------------------------------------------}
  500.  
  501. PROCEDURE SetupWindows;
  502. Var vScroll:   ControlHandle;  {used to create control}
  503.     hScroll:   ControlHandle;  {same thing, we could put them in global but the}
  504.                                {the window is global and it will have them}
  505. Begin
  506.   OneWindow :=  GetNewWindow(WindResID, Nil, POINTER(-1));
  507.   SetPort(OneWindow);  {so usableArea is correct}
  508.  
  509. {now setup the usable window area}
  510.   UsableArea := OneWindow^.portRect;                           {initialize it}
  511.   UsableArea.right :=   UsableArea.right - VSBarWidth;
  512.   UsableArea.bottom :=  UsableArea.bottom - HSBarHeight;
  513.  
  514. {now set up the scroll bar controls that this window will use}
  515.   vScroll := GetNewControl(VScrollBar,OneWindow);  {get vertical scroll bar}
  516.   hScroll := GetNewControl(HScrollBar,OneWindow);  {get horizontal scroll bar}
  517.  
  518. {our display is going to be 700 by 700 pixels so set min & max values}
  519. {Note: the window is 290 by 490}
  520.   SetCtlMin(hScroll,0);         {set the minimum value in vertical direction}
  521.   SetCtlMax(hScroll,210);       {set the maximum value in vertical direction}
  522.   SetCtlMin(vScroll,0);         {set the minimum value in horizontal direction}
  523.   SetCtlMax(vScroll,410);       {set the maximum value in horizontal direction}
  524.  
  525. {the current origin will be stored in the refcon of the window}
  526. (*  NOTE: its already been set in the resource file}
  527.   SetWRefCon(OneWindow, 0);             {initialize it to zero}
  528. *)
  529.  
  530. {all set so show the window}
  531.   ShowWindow(OneWindow);
  532.  
  533. {Note that the controls are brought in invisibily, show them}
  534. {when the window becomes active, hide them when its inactive}
  535. End;
  536.  
  537. {-----------------------------------------------------------------------------}
  538.  
  539. PROCEDURE SetUpThings;
  540. Begin
  541.   SetupWindows;         {do first so its low in heap}
  542.   SetupMenus;
  543.   SetupLimits;
  544.  
  545.   InitCursor;           {ready to go, so show the Arrow cursor}
  546. End;
  547.  
  548. {-----------------------------------------------------------------------------}
  549.  
  550. PROCEDURE CloseThings;
  551. Begin
  552. {close files, if you changed sys resources, UNchange them here be carefull}
  553. {about changing sys things, remember the Switcher could be around}
  554. End;
  555.  
  556. {-----------------------------------------------------------------------------}
  557.  
  558. BEGIN
  559.   InitThings;
  560.   SetUpThings;
  561.   MainEventLoop;
  562.   CloseThings;
  563. END.
  564.